home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / DJGPP / GPP257.ZIP / cplusinc / _string.h < prev    next >
C/C++ Source or Header  |  1993-11-13  |  38KB  |  1,321 lines

  1. // This may look like C code, but it is really -*- C++ -*-
  2. /* 
  3. Copyright (C) 1988 Free Software Foundation
  4.     written by Doug Lea (dl@rocky.oswego.edu)
  5.  
  6. This file is part of the GNU C++ Library.  This library is free
  7. software; you can redistribute it and/or modify it under the terms of
  8. the GNU Library General Public License as published by the Free
  9. Software Foundation; either version 2 of the License, or (at your
  10. option) any later version.  This library is distributed in the hope
  11. that it will be useful, but WITHOUT ANY WARRANTY; without even the
  12. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  13. PURPOSE.  See the GNU Library General Public License for more details.
  14. You should have received a copy of the GNU Library General Public
  15. License along with this library; if not, write to the Free Software
  16. Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  17. */
  18.  
  19.  
  20. #ifndef _String_h
  21. #ifdef __GNUG__
  22. #pragma interface
  23. #endif
  24. #define _String_h 1
  25.  
  26. #include <iostream.h>
  27. #ifdef __MSDOS__
  28. #include <_Regex.h>
  29. #else
  30. #include <Regex.h>
  31. #endif
  32.  
  33. struct StrRep                     // internal String representations
  34. {
  35.   unsigned short    len;         // string length 
  36.   unsigned short    sz;          // allocated space
  37.   char              s[1];        // the string starts here 
  38.                                  // (at least 1 char for trailing null)
  39.                                  // allocated & expanded via non-public fcts
  40. };
  41.  
  42. // primitive ops on StrReps -- nearly all String fns go through these.
  43.  
  44. StrRep*     Salloc(StrRep*, const char*, int, int);
  45. StrRep*     Scopy(StrRep*, StrRep*);
  46. StrRep*     Sresize(StrRep*, int);
  47. StrRep*     Scat(StrRep*, const char*, int, const char*, int);
  48. StrRep*     Scat(StrRep*, const char*, int,const char*,int, const char*,int);
  49. StrRep*     Sprepend(StrRep*, const char*, int);
  50. StrRep*     Sreverse(StrRep*, StrRep*);
  51. StrRep*     Supcase(StrRep*, StrRep*);
  52. StrRep*     Sdowncase(StrRep*, StrRep*);
  53. StrRep*     Scapitalize(StrRep*, StrRep*);
  54.  
  55. // These classes need to be defined in the order given
  56.  
  57. class String;
  58. class SubString;
  59.  
  60. class SubString
  61. {
  62.   friend class      String;
  63. protected:
  64.  
  65.   String&           S;        // The String I'm a substring of
  66.   unsigned short    pos;      // starting position in S's rep
  67.   unsigned short    len;      // length of substring
  68.  
  69.   void              assign(StrRep*, const char*, int = -1);
  70.                     SubString(String& x, int p, int l);
  71.                     SubString(const SubString& x);
  72.  
  73. public:
  74.  
  75. // Note there are no public constructors. SubStrings are always
  76. // created via String operations
  77.  
  78.                    ~SubString();
  79.  
  80.   void              operator =  (const String&     y);
  81.   void              operator =  (const SubString&  y);
  82.   void              operator =  (const char* t);
  83.   void              operator =  (char        c);
  84.  
  85. // return 1 if target appears anywhere in SubString; else 0
  86.  
  87.   int               contains(char        c) const;
  88.   int               contains(const String&     y) const;
  89.   int               contains(const SubString&  y) const;
  90.   int               contains(const char* t) const;
  91.   int               contains(const Regex&       r) const;
  92.  
  93. // return 1 if target matches entire SubString
  94.  
  95.   int               matches(const Regex&  r) const;
  96.  
  97. // IO 
  98.  
  99.   friend ostream&   operator<<(ostream& s, const SubString& x);
  100.  
  101. // status
  102.  
  103.   unsigned int      length() const;
  104.   int               empty() const;
  105.   const char*       chars() const;
  106.  
  107.   int               OK() const; 
  108.  
  109. };
  110.  
  111.  
  112. class String
  113. {
  114.   friend class      SubString;
  115.  
  116. protected:
  117.   StrRep*           rep;   // Strings are pointers to their representations
  118.  
  119. // some helper functions
  120.  
  121.   int               search(int, int, const char*, int = -1) const;
  122.   int               search(int, int, char) const;
  123.   int               match(int, int, int, const char*, int = -1) const;
  124.   int               _gsub(const char*, int, const char* ,int);
  125.   int               _gsub(const Regex&, const char*, int);
  126.   SubString         _substr(int, int);
  127.  
  128. public:
  129.  
  130. // constructors & assignment
  131.  
  132.                     String();
  133.                     String(const String& x);
  134.                     String(const SubString&  x);
  135.                     String(const char* t);
  136.                     String(const char* t, int len);
  137.                     String(char c);
  138.  
  139.                     ~String();
  140.  
  141.   void              operator =  (const String&     y);
  142.   void              operator =  (const char* y);
  143.   void              operator =  (char        c);
  144.   void              operator =  (const SubString&  y);
  145.  
  146. // concatenation
  147.  
  148.   void              operator += (const String&     y); 
  149.   void              operator += (const SubString&  y);
  150.   void              operator += (const char* t);
  151.   void              operator += (char        c);
  152.  
  153.   void              prepend(const String&     y); 
  154.   void              prepend(const SubString&  y);
  155.   void              prepend(const char* t);
  156.   void              prepend(char        c);
  157.  
  158.  
  159. // procedural versions:
  160. // concatenate first 2 args, store result in last arg
  161.  
  162.   friend void     cat(const String&, const String&, String&);
  163.   friend void     cat(const String&, const SubString&, String&);
  164.   friend void     cat(const String&, const char*, String&);
  165.   friend void     cat(const String&, char, String&);
  166.  
  167.   friend void     cat(const SubString&, const String&, String&);
  168.   friend void     cat(const SubString&, const SubString&, String&);
  169.   friend void     cat(const SubString&, const char*, String&);
  170.   friend void     cat(const SubString&, char, String&);
  171.  
  172.   friend void     cat(const char*, const String&, String&);
  173.   friend void     cat(const char*, const SubString&, String&);
  174.   friend void     cat(const char*, const char*, String&);
  175.   friend void     cat(const char*, char, String&);
  176.  
  177. // double concatenation, by request. (yes, there are too many versions, 
  178. // but if one is supported, then the others should be too...)
  179. // Concatenate first 3 args, store in last arg
  180.  
  181.   friend void     cat(const String&,const String&, const String&,String&);
  182.   friend void     cat(const String&,const String&,const SubString&,String&);
  183.   friend void     cat(const String&,const String&, const char*, String&);
  184.   friend void     cat(const String&,const String&, char, String&);
  185.   friend void     cat(const String&,const SubString&,const String&,String&);
  186.   friend void     cat(const String&,const SubString&,const SubString&,String&);
  187.   friend void     cat(const String&,const SubString&, const char*, String&);
  188.   friend void     cat(const String&,const SubString&, char, String&);
  189.   friend void     cat(const String&,const char*, const String&,    String&);
  190.   friend void     cat(const String&,const char*, const SubString&, String&);
  191.   friend void     cat(const String&,const char*, const char*, String&);
  192.   friend void     cat(const String&,const char*, char, String&);
  193.  
  194.   friend void     cat(const char*, const String&, const String&,String&);
  195.   friend void     cat(const char*,const String&,const SubString&,String&);
  196.   friend void     cat(const char*,const String&, const char*, String&);
  197.   friend void     cat(const char*,const String&, char, String&);
  198.   friend void     cat(const char*,const SubString&,const String&,String&);
  199.   friend void     cat(const char*,const SubString&,const SubString&,String&);
  200.   friend void     cat(const char*,const SubString&, const char*, String&);
  201.   friend void     cat(const char*,const SubString&, char, String&);
  202.   friend void     cat(const char*,const char*, const String&,    String&);
  203.   friend void     cat(const char*,const char*, const SubString&, String&);
  204.   friend void     cat(const char*,const char*, const char*, String&);
  205.   friend void     cat(const char*,const char*, char, String&);
  206.  
  207.  
  208. // searching & matching
  209.  
  210. // return position of target in string or -1 for failure
  211.  
  212.   int               index(char        c, int startpos = 0) const;      
  213.   int               index(const String&     y, int startpos = 0) const;      
  214.   int               index(const SubString&  y, int startpos = 0) const;      
  215.   int               index(const char* t, int startpos = 0) const;  
  216.   int               index(const Regex&      r, int startpos = 0) const;       
  217.  
  218. // return 1 if target appears anyhere in String; else 0
  219.  
  220.   int               contains(char        c) const;
  221.   int               contains(const String&     y) const;
  222.   int               contains(const SubString&  y) const;
  223.   int               contains(const char* t) const;
  224.   int               contains(const Regex&      r) const;
  225.  
  226. // return 1 if target appears anywhere after position pos 
  227. // (or before, if pos is negative) in String; else 0
  228.  
  229.   int               contains(char        c, int pos) const;
  230.   int               contains(const String&     y, int pos) const;
  231.   int               contains(const SubString&  y, int pos) const;
  232.   int               contains(const char* t, int pos) const;
  233.   int               contains(const Regex&      r, int pos) const;
  234.  
  235. // return 1 if target appears at position pos in String; else 0
  236.  
  237.   int               matches(char        c, int pos = 0) const;
  238.   int               matches(const String&     y, int pos = 0) const;
  239.   int               matches(const SubString&  y, int pos = 0) const;
  240.   int               matches(const char* t, int pos = 0) const;
  241.   int               matches(const Regex&      r, int pos = 0) const;
  242.  
  243. //  return number of occurences of target in String
  244.  
  245.   int               freq(char        c) const; 
  246.   int               freq(const String&     y) const;
  247.   int               freq(const SubString&  y) const;
  248.   int               freq(const char* t) const;
  249.  
  250. // SubString extraction
  251.  
  252. // Note that you can't take a substring of a const String, since
  253. // this leaves open the possiblility of indirectly modifying the
  254. // String through the SubString
  255.  
  256.   SubString         at(int         pos, int len);
  257.   SubString         operator () (int         pos, int len); // synonym for at
  258.  
  259.   SubString         at(const String&     x, int startpos = 0); 
  260.   SubString         at(const SubString&  x, int startpos = 0); 
  261.   SubString         at(const char* t, int startpos = 0);
  262.   SubString         at(char        c, int startpos = 0);
  263.   SubString         at(const Regex&      r, int startpos = 0); 
  264.  
  265.   SubString         before(int          pos);
  266.   SubString         before(const String&      x, int startpos = 0);
  267.   SubString         before(const SubString&   x, int startpos = 0);
  268.   SubString         before(const char*  t, int startpos = 0);
  269.   SubString         before(char         c, int startpos = 0);
  270.   SubString         before(const Regex&       r, int startpos = 0);
  271.  
  272.   SubString         through(int          pos);
  273.   SubString         through(const String&      x, int startpos = 0);
  274.   SubString         through(const SubString&   x, int startpos = 0);
  275.   SubString         through(const char*  t, int startpos = 0);
  276.   SubString         through(char         c, int startpos = 0);
  277.   SubString         through(const Regex&       r, int startpos = 0);
  278.  
  279.   SubString         from(int          pos);
  280.   SubString         from(const String&      x, int startpos = 0);
  281.   SubString         from(const SubString&   x, int startpos = 0);
  282.   SubString         from(const char*  t, int startpos = 0);
  283.   SubString         from(char         c, int startpos = 0);
  284.   SubString         from(const Regex&       r, int startpos = 0);
  285.  
  286.   SubString         after(int         pos);
  287.   SubString         after(const String&     x, int startpos = 0);
  288.   SubString         after(const SubString&  x, int startpos = 0);
  289.   SubString         after(const char* t, int startpos = 0);
  290.   SubString         after(char        c, int startpos = 0);
  291.   SubString         after(const Regex&      r, int startpos = 0);
  292.  
  293.  
  294. // deletion
  295.  
  296. // delete len chars starting at pos
  297.   void              del(int         pos, int len);
  298.  
  299. // delete the first occurrence of target after startpos
  300.  
  301.   void              del(const String&     y, int startpos = 0);
  302.   void              del(const SubString&  y, int startpos = 0);
  303.   void              del(const char* t, int startpos = 0);
  304.   void              del(char        c, int startpos = 0);
  305.   void              del(const Regex&      r, int startpos = 0);
  306.  
  307. // global substitution: substitute all occurrences of pat with repl
  308.  
  309.   int               gsub(const String&     pat, const String&     repl);
  310.   int               gsub(const SubString&  pat, const String&     repl);
  311.   int               gsub(const char* pat, const String&     repl);
  312.   int               gsub(const char* pat, const char* repl);
  313.   int               gsub(const Regex&      pat, const String&     repl);
  314.  
  315. // friends & utilities
  316.  
  317. // split string into array res at separators; return number of elements
  318.  
  319.   friend int        split(const String& x, String res[], int maxn, 
  320.                           const String& sep);
  321.   friend int        split(const String& x, String res[], int maxn, 
  322.                           const Regex&  sep);
  323.  
  324.   friend String     common_prefix(const String& x, const String& y, 
  325.                                   int startpos = 0);
  326.   friend String     common_suffix(const String& x, const String& y, 
  327.                                   int startpos = -1);
  328.   friend String     replicate(char        c, int n);
  329.   friend String     replicate(const String&     y, int n);
  330.   friend String     join(String src[], int n, const String& sep);
  331.  
  332. // simple builtin transformations
  333.  
  334.   friend String     reverse(const String& x);
  335.   friend String     upcase(const String& x);
  336.   friend String     downcase(const String& x);
  337.   friend String     capitalize(const String& x);
  338.  
  339. // in-place versions of above
  340.  
  341.   void              reverse();
  342.   void              upcase();
  343.   void              downcase();
  344.   void              capitalize();
  345.  
  346. // element extraction
  347.  
  348.   char&             operator [] (int i);
  349.   char              elem(int i) const;
  350.   char              firstchar() const;
  351.   char              lastchar() const;
  352.  
  353. // conversion
  354.  
  355.                     operator const char*() const;
  356.   const char*       chars() const;
  357.  
  358.  
  359. // IO
  360.  
  361.   friend ostream&   operator<<(ostream& s, const String& x);
  362.   friend ostream&   operator<<(ostream& s, const SubString& x);
  363.   friend istream&   operator>>(istream& s, String& x);
  364.  
  365.   friend int        readline(istream& s, String& x, 
  366.                              char terminator = '\n',
  367.                              int discard_terminator = 1);
  368.  
  369. // status
  370.  
  371.   unsigned int      length() const;
  372.   int               empty() const;
  373.  
  374. // preallocate some space for String
  375.   void              alloc(int newsize);
  376.  
  377. // report current allocation (not length!)
  378.  
  379.   int               allocation() const;
  380.  
  381.  
  382.   void     error(const char* msg) const;
  383.  
  384.   int               OK() const;
  385. };
  386.  
  387. typedef String StrTmp; // for backward compatibility
  388.  
  389. // other externs
  390.  
  391. int        compare(const String&    x, const String&     y);
  392. int        compare(const String&    x, const SubString&  y);
  393. int        compare(const String&    x, const char* y);
  394. int        compare(const SubString& x, const String&     y);
  395. int        compare(const SubString& x, const SubString&  y);
  396. int        compare(const SubString& x, const char* y);
  397. int        fcompare(const String&   x, const String&     y); // ignore case
  398.  
  399. extern StrRep  _nilStrRep;
  400. extern String _nilString;
  401.  
  402. // other inlines
  403.  
  404. String operator + (const String& x, const String& y);
  405. String operator + (const String& x, const SubString& y);
  406. String operator + (const String& x, const char* y);
  407. String operator + (const String& x, char y);
  408. String operator + (const SubString& x, const String& y);
  409. String operator + (const SubString& x, const SubString& y);
  410. String operator + (const SubString& x, const char* y);
  411. String operator + (const SubString& x, char y);
  412. String operator + (const char* x, const String& y);
  413. String operator + (const char* x, const SubString& y);
  414.  
  415. int operator==(const String& x, const String& y); 
  416. int operator!=(const String& x, const String& y);
  417. int operator> (const String& x, const String& y);
  418. int operator>=(const String& x, const String& y);
  419. int operator< (const String& x, const String& y);
  420. int operator<=(const String& x, const String& y);
  421. int operator==(const String& x, const SubString&  y);
  422. int operator!=(const String& x, const SubString&  y);
  423. int operator> (const String& x, const SubString&  y);
  424. int operator>=(const String& x, const SubString&  y);
  425. int operator< (const String& x, const SubString&  y);
  426. int operator<=(const String& x, const SubString&  y);
  427. int operator==(const String& x, const char* t);
  428. int operator!=(const String& x, const char* t);
  429. int operator> (const String& x, const char* t);
  430. int operator>=(const String& x, const char* t);
  431. int operator< (const String& x, const char* t);
  432. int operator<=(const String& x, const char* t);
  433. int operator==(const SubString& x, const String& y);
  434. int operator!=(const SubString& x, const String& y);
  435. int operator> (const SubString& x, const String& y);
  436. int operator>=(const SubString& x, const String& y);
  437. int operator< (const SubString& x, const String& y);
  438. int operator<=(const SubString& x, const String& y);
  439. int operator==(const SubString& x, const SubString&  y);
  440. int operator!=(const SubString& x, const SubString&  y);
  441. int operator> (const SubString& x, const SubString&  y);
  442. int operator>=(const SubString& x, const SubString&  y);
  443. int operator< (const SubString& x, const SubString&  y);
  444. int operator<=(const SubString& x, const SubString&  y);
  445. int operator==(const SubString& x, const char* t);
  446. int operator!=(const SubString& x, const char* t);
  447. int operator> (const SubString& x, const char* t);
  448. int operator>=(const SubString& x, const char* t);
  449. int operator< (const SubString& x, const char* t);
  450. int operator<=(const SubString& x, const char* t);
  451.  
  452.  
  453. // status reports, needed before defining other things
  454.  
  455. inline unsigned int String::length() const {  return rep->len; }
  456. inline int         String::empty() const { return rep->len == 0; }
  457. inline const char* String::chars() const { return &(rep->s[0]); }
  458. inline int         String::allocation() const { return rep->sz; }
  459. inline void        String::alloc(int newsize) { rep = Sresize(rep, newsize); }
  460.  
  461. inline unsigned int SubString::length() const { return len; }
  462. inline int         SubString::empty() const { return len == 0; }
  463. inline const char* SubString::chars() const { return &(S.rep->s[pos]); }
  464.  
  465.  
  466. // constructors
  467.  
  468. inline String::String() 
  469.   : rep(&_nilStrRep) {}
  470. inline String::String(const String& x) 
  471.   : rep(Scopy(0, x.rep)) {}
  472. inline String::String(const char* t) 
  473.   : rep(Salloc(0, t, -1, -1)) {}
  474. inline String::String(const char* t, int tlen)
  475.   : rep(Salloc(0, t, tlen, tlen)) {}
  476. inline String::String(const SubString& y)
  477.   : rep(Salloc(0, y.chars(), y.length(), y.length())) {}
  478. inline String::String(char c) 
  479.   : rep(Salloc(0, &c, 1, 1)) {}
  480.  
  481. inline String::~String() { if (rep != &_nilStrRep) delete rep; }
  482.  
  483. inline SubString::SubString(const SubString& x)
  484.   :S(x.S), pos(x.pos), len(x.len) {}
  485. inline SubString::SubString(String& x, int first, int l)
  486.   :S(x), pos(first), len(l) {}
  487.  
  488. inline SubString::~SubString() {}
  489.  
  490. // assignment
  491.  
  492. inline void String::operator =  (const String& y)
  493.   rep = Scopy(rep, y.rep);
  494. }
  495.  
  496. inline void String::operator=(const char* t)
  497. {
  498.   rep = Salloc(rep, t, -1, -1); 
  499. }
  500.  
  501. inline void String::operator=(const SubString&  y)
  502. {
  503.   rep = Salloc(rep, y.chars(), y.length(), y.length());
  504. }
  505.  
  506. inline void String::operator=(char c)
  507. {
  508.   rep = Salloc(rep, &c, 1, 1); 
  509. }
  510.  
  511.  
  512. inline void SubString::operator = (const char* ys)
  513. {
  514.   assign(0, ys);
  515. }
  516.  
  517. inline void SubString::operator = (char ch)
  518. {
  519.   assign(0, &ch, 1);
  520. }
  521.  
  522. inline void SubString::operator = (const String& y)
  523. {
  524.   assign(y.rep, y.chars(), y.length());
  525. }
  526.  
  527. inline void SubString::operator = (const SubString& y)
  528. {
  529.   assign(y.S.rep, y.chars(), y.length());
  530. }
  531.  
  532. // Zillions of cats...
  533.  
  534. inline void cat(const String& x, const String& y, String& r)
  535. {
  536.   r.rep = Scat(r.rep, x.chars(), x.length(), y.chars(), y.length());
  537. }
  538.  
  539. inline void cat(const String& x, const SubString& y, String& r)
  540. {
  541.   r.rep = Scat(r.rep, x.chars(), x.length(), y.chars(), y.length());
  542. }
  543.  
  544. inline void cat(const String& x, const char* y, String& r)
  545. {
  546.   r.rep = Scat(r.rep, x.chars(), x.length(), y, -1);
  547. }
  548.  
  549. inline void cat(const String& x, char y, String& r)
  550. {
  551.   r.rep = Scat(r.rep, x.chars(), x.length(), &y, 1);
  552. }
  553.  
  554. inline void cat(const SubString& x, const String& y, String& r)
  555. {
  556.   r.rep = Scat(r.rep, x.chars(), x.length(), y.chars(), y.length());
  557. }
  558.  
  559. inline void cat(const SubString& x, const SubString& y, String& r)
  560. {
  561.   r.rep = Scat(r.rep, x.chars(), x.length(), y.chars(), y.length());
  562. }
  563.  
  564. inline void cat(const SubString& x, const char* y, String& r)
  565. {
  566.   r.rep = Scat(r.rep, x.chars(), x.length(), y, -1);
  567. }
  568.  
  569. inline void cat(const SubString& x, char y, String& r)
  570. {
  571.   r.rep = Scat(r.rep, x.chars(), x.length(), &y, 1);
  572. }
  573.  
  574. inline void cat(const char* x, const String& y, String& r)
  575. {
  576.   r.rep = Scat(r.rep, x, -1, y.chars(), y.length());
  577. }
  578.  
  579. inline void cat(const char* x, const SubString& y, String& r)
  580. {
  581.   r.rep = Scat(r.rep, x, -1, y.chars(), y.length());
  582. }
  583.  
  584. inline void cat(const char* x, const char* y, String& r)
  585. {
  586.   r.rep = Scat(r.rep, x, -1, y, -1);
  587. }
  588.  
  589. inline void cat(const char* x, char y, String& r)
  590. {
  591.   r.rep = Scat(r.rep, x, -1, &y, 1);
  592. }
  593.  
  594. inline void cat(const String& a, const String& x, const String& y, String& r)
  595. {
  596.   r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), y.chars(), y.length());
  597. }
  598.  
  599. inline void cat(const String& a, const String& x, const SubString& y, String& r)
  600. {
  601.   r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), y.chars(), y.length());
  602. }
  603.  
  604. inline void cat(const String& a, const String& x, const char* y, String& r)
  605. {
  606.   r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), y, -1);
  607. }
  608.  
  609. inline void cat(const String& a, const String& x, char y, String& r)
  610. {
  611.   r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), &y, 1);
  612. }
  613.  
  614. inline void cat(const String& a, const SubString& x, const String& y, String& r)
  615. {
  616.   r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), y.chars(), y.length());
  617. }
  618.  
  619. inline void cat(const String& a, const SubString& x, const SubString& y, String& r)
  620. {
  621.   r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), y.chars(), y.length());
  622. }
  623.  
  624. inline void cat(const String& a, const SubString& x, const char* y, String& r)
  625. {
  626.   r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), y, -1);
  627. }
  628.  
  629. inline void cat(const String& a, const SubString& x, char y, String& r)
  630. {
  631.   r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), &y, 1);
  632. }
  633.  
  634. inline void cat(const String& a, const char* x, const String& y, String& r)
  635. {
  636.   r.rep = Scat(r.rep, a.chars(), a.length(), x, -1, y.chars(), y.length());
  637. }
  638.  
  639. inline void cat(const String& a, const char* x, const SubString& y, String& r)
  640. {
  641.   r.rep = Scat(r.rep, a.chars(), a.length(), x, -1, y.chars(), y.length());
  642. }
  643.  
  644. inline void cat(const String& a, const char* x, const char* y, String& r)
  645. {
  646.   r.rep = Scat(r.rep, a.chars(), a.length(), x, -1, y, -1);
  647. }
  648.  
  649. inline void cat(const String& a, const char* x, char y, String& r)
  650. {
  651.   r.rep = Scat(r.rep, a.chars(), a.length(), x, -1, &y, 1);
  652. }
  653.  
  654.  
  655. inline void cat(const char* a, const String& x, const String& y, String& r)
  656. {
  657.   r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), y.chars(), y.length());
  658. }
  659.  
  660. inline void cat(const char* a, const String& x, const SubString& y, String& r)
  661. {
  662.   r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), y.chars(), y.length());
  663. }
  664.  
  665. inline void cat(const char* a, const String& x, const char* y, String& r)
  666. {
  667.   r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), y, -1);
  668. }
  669.  
  670. inline void cat(const char* a, const String& x, char y, String& r)
  671. {
  672.   r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), &y, 1);
  673. }
  674.  
  675. inline void cat(const char* a, const SubString& x, const String& y, String& r)
  676. {
  677.   r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), y.chars(), y.length());
  678. }
  679.  
  680. inline void cat(const char* a, const SubString& x, const SubString& y, String& r)
  681. {
  682.   r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), y.chars(), y.length());
  683. }
  684.  
  685. inline void cat(const char* a, const SubString& x, const char* y, String& r)
  686. {
  687.   r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), y, -1);
  688. }
  689.  
  690. inline void cat(const char* a, const SubString& x, char y, String& r)
  691. {
  692.   r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), &y, 1);
  693. }
  694.  
  695. inline void cat(const char* a, const char* x, const String& y, String& r)
  696. {
  697.   r.rep = Scat(r.rep, a, -1, x, -1, y.chars(), y.length());
  698. }
  699.  
  700. inline void cat(const char* a, const char* x, const SubString& y, String& r)
  701. {
  702.   r.rep = Scat(r.rep, a, -1, x, -1, y.chars(), y.length());
  703. }
  704.  
  705. inline void cat(const char* a, const char* x, const char* y, String& r)
  706. {
  707.   r.rep = Scat(r.rep, a, -1, x, -1, y, -1);
  708. }
  709.  
  710. inline void cat(const char* a, const char* x, char y, String& r)
  711. {
  712.   r.rep = Scat(r.rep, a, -1, x, -1, &y, 1);
  713. }
  714.  
  715.  
  716. // operator versions
  717.  
  718. inline void String::operator +=(const String& y)
  719. {
  720.   cat(*this, y, *this);
  721. }
  722.  
  723. inline void String::operator +=(const SubString& y)
  724. {
  725.   cat(*this, y, *this);
  726. }
  727.  
  728. inline void String::operator += (const char* y)
  729. {
  730.   cat(*this, y, *this);
  731. }
  732.  
  733. inline void String:: operator +=(char y)
  734. {
  735.   cat(*this, y, *this);
  736. }
  737.  
  738. // constructive concatenation
  739.  
  740. #if defined(__GNUG__) && !defined(NO_NRV)
  741.  
  742. inline String operator + (const String& x, const String& y) return r;
  743. {
  744.   cat(x, y, r);
  745. }
  746.  
  747. inline String operator + (const String& x, const SubString& y) return r;
  748. {
  749.   cat(x, y, r);
  750. }
  751.  
  752. inline String operator + (const String& x, const char* y) return r;
  753. {
  754.   cat(x, y, r);
  755. }
  756.  
  757. inline String operator + (const String& x, char y) return r;
  758. {
  759.   cat(x, y, r);
  760. }
  761.  
  762. inline String operator + (const SubString& x, const String& y) return r;
  763. {
  764.   cat(x, y, r);
  765. }
  766.  
  767. inline String operator + (const SubString& x, const SubString& y) return r;
  768. {
  769.   cat(x, y, r);
  770. }
  771.  
  772. inline String operator + (const SubString& x, const char* y) return r;
  773. {
  774.   cat(x, y, r);
  775. }
  776.  
  777. inline String operator + (const SubString& x, char y) return r;
  778. {
  779.   cat(x, y, r);
  780. }
  781.  
  782. inline String operator + (const char* x, const String& y) return r;
  783. {
  784.   cat(x, y, r);
  785. }
  786.  
  787. inline String operator + (const char* x, const SubString& y) return r;
  788. {
  789.   cat(x, y, r);
  790. }
  791.  
  792. inline String reverse(const String& x) return r;
  793. {
  794.   r.rep = Sreverse(x.rep, r.rep);
  795. }
  796.  
  797. inline String upcase(const String& x) return r;
  798. {
  799.   r.rep = Supcase(x.rep, r.rep);
  800. }
  801.  
  802. inline String downcase(const String& x) return r;
  803. {
  804.   r.rep = Sdowncase(x.rep, r.rep);
  805. }
  806.  
  807. inline String capitalize(const String& x) return r;
  808. {
  809.   r.rep = Scapitalize(x.rep, r.rep);
  810. }
  811.  
  812. #else /* NO_NRV */
  813.  
  814. inline String operator + (const String& x, const String& y)
  815. {
  816.   String r;  cat(x, y, r);  return r;
  817. }
  818.  
  819. inline String operator + (const String& x, const SubString& y) 
  820. {
  821.   String r; cat(x, y, r); return r;
  822. }
  823.  
  824. inline String operator + (const String& x, const char* y) 
  825. {
  826.   String r; cat(x, y, r); return r;
  827. }
  828.  
  829. inline String operator + (const String& x, char y) 
  830. {
  831.   String r; cat(x, y, r); return r;
  832. }
  833.  
  834. inline String operator + (const SubString& x, const String& y) 
  835. {
  836.   String r; cat(x, y, r); return r;
  837. }
  838.  
  839. inline String operator + (const SubString& x, const SubString& y) 
  840. {
  841.   String r; cat(x, y, r); return r;
  842. }
  843.  
  844. inline String operator + (const SubString& x, const char* y) 
  845. {
  846.   String r; cat(x, y, r); return r;
  847. }
  848.  
  849. inline String operator + (const SubString& x, char y) 
  850. {
  851.   String r; cat(x, y, r); return r;
  852. }
  853.  
  854. inline String operator + (const char* x, const String& y) 
  855. {
  856.   String r; cat(x, y, r); return r;
  857. }
  858.  
  859. inline String operator + (const char* x, const SubString& y) 
  860. {
  861.   String r; cat(x, y, r); return r;
  862. }
  863.  
  864. inline String reverse(const String& x) 
  865. {
  866.   String r; r.rep = Sreverse(x.rep, r.rep); return r;
  867. }
  868.  
  869. inline String upcase(const String& x) 
  870. {
  871.   String r; r.rep = Supcase(x.rep, r.rep); return r;
  872. }
  873.  
  874. inline String downcase(const String& x) 
  875. {
  876.   String r; r.rep = Sdowncase(x.rep, r.rep); return r;
  877. }
  878.  
  879. inline String capitalize(const String& x) 
  880. {
  881.   String r; r.rep = Scapitalize(x.rep, r.rep); return r;
  882. }
  883.  
  884. #endif
  885.  
  886. // prepend
  887.  
  888. inline void String::prepend(const String& y)
  889. {
  890.   rep = Sprepend(rep, y.chars(), y.length());
  891. }
  892.  
  893. inline void String::prepend(const char* y)
  894. {
  895.   rep = Sprepend(rep, y, -1); 
  896. }
  897.  
  898. inline void String::prepend(char y)
  899. {
  900.   rep = Sprepend(rep, &y, 1); 
  901. }
  902.  
  903. inline void String::prepend(const SubString& y)
  904. {
  905.   rep = Sprepend(rep, y.chars(), y.length());
  906. }
  907.  
  908. // misc transformations
  909.  
  910.  
  911. inline void String::reverse()
  912. {
  913.   rep = Sreverse(rep, rep);
  914. }
  915.  
  916.  
  917. inline void String::upcase()
  918. {
  919.   rep = Supcase(rep, rep);
  920. }
  921.  
  922.  
  923. inline void String::downcase()
  924. {
  925.   rep = Sdowncase(rep, rep);
  926. }
  927.  
  928.  
  929. inline void String::capitalize()
  930. {
  931.   rep = Scapitalize(rep, rep);
  932. }
  933.  
  934. // element extraction
  935.  
  936. inline char&  String::operator [] (int i) 
  937.   if (((unsigned)i) >= length()) error("invalid index");
  938.   return rep->s[i];
  939. }
  940.  
  941. inline char  String::elem (int i) const
  942.   if (((unsigned)i) >= length()) error("invalid index");
  943.   return rep->s[i];
  944. }
  945.  
  946. inline char  String::firstchar() const
  947.   return elem(0);
  948. }
  949.  
  950. inline char  String::lastchar() const
  951.   return elem(length() - 1);
  952. }
  953.  
  954. // searching
  955.  
  956. inline int String::index(char c, int startpos) const
  957. {
  958.   return search(startpos, length(), c);
  959. }
  960.  
  961. inline int String::index(const char* t, int startpos) const
  962. {   
  963.   return search(startpos, length(), t);
  964. }
  965.  
  966. inline int String::index(const String& y, int startpos) const
  967. {   
  968.   return search(startpos, length(), y.chars(), y.length());
  969. }
  970.  
  971. inline int String::index(const SubString& y, int startpos) const
  972. {   
  973.   return search(startpos, length(), y.chars(), y.length());
  974. }
  975.  
  976. inline int String::index(const Regex& r, int startpos) const
  977. {
  978.   int unused;  return r.search(chars(), length(), unused, startpos);
  979. }
  980.  
  981. inline int String::contains(char c) const
  982. {
  983.   return search(0, length(), c) >= 0;
  984. }
  985.  
  986. inline int String::contains(const char* t) const
  987. {   
  988.   return search(0, length(), t) >= 0;
  989. }
  990.  
  991. inline int String::contains(const String& y) const
  992. {   
  993.   return search(0, length(), y.chars(), y.length()) >= 0;
  994. }
  995.  
  996. inline int String::contains(const SubString& y) const
  997. {   
  998.   return search(0, length(), y.chars(), y.length()) >= 0;
  999. }
  1000.  
  1001. inline int String::contains(char c, int p) const
  1002. {
  1003.   return match(p, length(), 0, &c, 1) >= 0;
  1004. }
  1005.  
  1006. inline int String::contains(const char* t, int p) const
  1007. {
  1008.   return match(p, length(), 0, t) >= 0;
  1009. }
  1010.  
  1011. inline int String::contains(const String& y, int p) const
  1012. {
  1013.   return match(p, length(), 0, y.chars(), y.length()) >= 0;
  1014. }
  1015.  
  1016. inline int String::contains(const SubString& y, int p) const
  1017. {
  1018.   return match(p, length(), 0, y.chars(), y.length()) >= 0;
  1019. }
  1020.  
  1021. inline int String::contains(const Regex& r) const
  1022. {
  1023.   int unused;  return r.search(chars(), length(), unused, 0) >= 0;
  1024. }
  1025.  
  1026. inline int String::contains(const Regex& r, int p) const
  1027. {
  1028.   return r.match(chars(), length(), p) >= 0;
  1029. }
  1030.  
  1031.  
  1032. inline int String::matches(const SubString& y, int p) const
  1033. {
  1034.   return match(p, length(), 1, y.chars(), y.length()) >= 0;
  1035. }
  1036.  
  1037. inline int String::matches(const String& y, int p) const
  1038. {
  1039.   return match(p, length(), 1, y.chars(), y.length()) >= 0;
  1040. }
  1041.  
  1042. inline int String::matches(const char* t, int p) const
  1043. {
  1044.   return match(p, length(), 1, t) >= 0;
  1045. }
  1046.  
  1047. inline int String::matches(char c, int p) const
  1048. {
  1049.   return match(p, length(), 1, &c, 1) >= 0;
  1050. }
  1051.  
  1052. inline int String::matches(const Regex& r, int p) const
  1053. {
  1054.   int l = (p < 0)? -p : length() - p;
  1055.   return r.match(chars(), length(), p) == l;
  1056. }
  1057.  
  1058.  
  1059. inline int SubString::contains(const char* t) const
  1060. {   
  1061.   return S.search(pos, pos+len, t) >= 0;
  1062. }
  1063.  
  1064. inline int SubString::contains(const String& y) const
  1065. {   
  1066.   return S.search(pos, pos+len, y.chars(), y.length()) >= 0;
  1067. }
  1068.  
  1069. inline int SubString::contains(const SubString&  y) const
  1070. {   
  1071.   return S.search(pos, pos+len, y.chars(), y.length()) >= 0;
  1072. }
  1073.  
  1074. inline int SubString::contains(char c) const
  1075. {
  1076.   return S.search(pos, pos+len, c) >= 0;
  1077. }
  1078.  
  1079. inline int SubString::contains(const Regex& r) const
  1080. {
  1081.   int unused;  return r.search(chars(), len, unused, 0) >= 0;
  1082. }
  1083.  
  1084. inline int SubString::matches(const Regex& r) const
  1085. {
  1086.   return r.match(chars(), len, 0) == len;
  1087. }
  1088.  
  1089.  
  1090. inline int String::gsub(const String& pat, const String& r)
  1091. {
  1092.   return _gsub(pat.chars(), pat.length(), r.chars(), r.length());
  1093. }
  1094.  
  1095. inline int String::gsub(const SubString&  pat, const String& r)
  1096. {
  1097.   return _gsub(pat.chars(), pat.length(), r.chars(), r.length());
  1098. }
  1099.  
  1100. inline int String::gsub(const Regex& pat, const String& r)
  1101. {
  1102.   return _gsub(pat, r.chars(), r.length());
  1103. }
  1104.  
  1105. inline int String::gsub(const char* pat, const String& r)
  1106. {
  1107.   return _gsub(pat, -1, r.chars(), r.length());
  1108. }
  1109.  
  1110. inline int String::gsub(const char* pat, const char* r)
  1111. {
  1112.   return _gsub(pat, -1, r, -1);
  1113. }
  1114.  
  1115.  
  1116.  
  1117. inline  ostream& operator<<(ostream& s, const String& x)
  1118. {
  1119.    s << x.chars(); return s;
  1120. }
  1121.  
  1122. // a zillion comparison operators
  1123.  
  1124. inline int operator==(const String& x, const String& y) 
  1125. {
  1126.   return compare(x, y) == 0; 
  1127. }
  1128.  
  1129. inline int operator!=(const String& x, const String& y)
  1130. {
  1131.   return compare(x, y) != 0; 
  1132. }
  1133.  
  1134. inline int operator>(const String& x, const String& y)
  1135. {
  1136.   return compare(x, y) > 0; 
  1137. }
  1138.  
  1139. inline int operator>=(const String& x, const String& y)
  1140. {
  1141.   return compare(x, y) >= 0; 
  1142. }
  1143.  
  1144. inline int operator<(const String& x, const String& y)
  1145. {
  1146.   return compare(x, y) < 0; 
  1147. }
  1148.  
  1149. inline int operator<=(const String& x, const String& y)
  1150. {
  1151.   return compare(x, y) <= 0; 
  1152. }
  1153.  
  1154. inline int operator==(const String& x, const SubString&  y) 
  1155. {
  1156.   return compare(x, y) == 0; 
  1157. }
  1158.  
  1159. inline int operator!=(const String& x, const SubString&  y)
  1160. {
  1161.   return compare(x, y) != 0; 
  1162. }
  1163.  
  1164. inline int operator>(const String& x, const SubString&  y)      
  1165. {
  1166.   return compare(x, y) > 0; 
  1167. }
  1168.  
  1169. inline int operator>=(const String& x, const SubString&  y)
  1170. {
  1171.   return compare(x, y) >= 0; 
  1172. }
  1173.  
  1174. inline int operator<(const String& x, const SubString&  y) 
  1175. {
  1176.   return compare(x, y) < 0; 
  1177. }
  1178.  
  1179. inline int operator<=(const String& x, const SubString&  y)
  1180. {
  1181.   return compare(x, y) <= 0; 
  1182. }
  1183.  
  1184. inline int operator==(const String& x, const char* t) 
  1185. {
  1186.   return compare(x, t) == 0; 
  1187. }
  1188.  
  1189. inline int operator!=(const String& x, const char* t) 
  1190. {
  1191.   return compare(x, t) != 0; 
  1192. }
  1193.  
  1194. inline int operator>(const String& x, const char* t)  
  1195. {
  1196.   return compare(x, t) > 0; 
  1197. }
  1198.  
  1199. inline int operator>=(const String& x, const char* t) 
  1200. {
  1201.   return compare(x, t) >= 0; 
  1202. }
  1203.  
  1204. inline int operator<(const String& x, const char* t)  
  1205. {
  1206.   return compare(x, t) < 0; 
  1207. }
  1208.  
  1209. inline int operator<=(const String& x, const char* t) 
  1210. {
  1211.   return compare(x, t) <= 0; 
  1212. }
  1213.  
  1214. inline int operator==(const SubString& x, const String& y) 
  1215. {
  1216.   return compare(y, x) == 0; 
  1217. }
  1218.  
  1219. inline int operator!=(const SubString& x, const String& y)
  1220. {
  1221.   return compare(y, x) != 0;
  1222. }
  1223.  
  1224. inline int operator>(const SubString& x, const String& y)      
  1225. {
  1226.   return compare(y, x) < 0;
  1227. }
  1228.  
  1229. inline int operator>=(const SubString& x, const String& y)     
  1230. {
  1231.   return compare(y, x) <= 0;
  1232. }
  1233.  
  1234. inline int operator<(const SubString& x, const String& y)      
  1235. {
  1236.   return compare(y, x) > 0;
  1237. }
  1238.  
  1239. inline int operator<=(const SubString& x, const String& y)     
  1240. {
  1241.   return compare(y, x) >= 0;
  1242. }
  1243.  
  1244. inline int operator==(const SubString& x, const SubString&  y) 
  1245. {
  1246.   return compare(x, y) == 0; 
  1247. }
  1248.  
  1249. inline int operator!=(const SubString& x, const SubString&  y)
  1250. {
  1251.   return compare(x, y) != 0;
  1252. }
  1253.  
  1254. inline int operator>(const SubString& x, const SubString&  y)      
  1255. {
  1256.   return compare(x, y) > 0;
  1257. }
  1258.  
  1259. inline int operator>=(const SubString& x, const SubString&  y)
  1260. {
  1261.   return compare(x, y) >= 0;
  1262. }
  1263.  
  1264. inline int operator<(const SubString& x, const SubString&  y) 
  1265. {
  1266.   return compare(x, y) < 0;
  1267. }
  1268.  
  1269. inline int operator<=(const SubString& x, const SubString&  y)
  1270. {
  1271.   return compare(x, y) <= 0;
  1272. }
  1273.  
  1274. inline int operator==(const SubString& x, const char* t) 
  1275. {
  1276.   return compare(x, t) == 0; 
  1277. }
  1278.  
  1279. inline int operator!=(const SubString& x, const char* t) 
  1280. {
  1281.   return compare(x, t) != 0;
  1282. }
  1283.  
  1284. inline int operator>(const SubString& x, const char* t)  
  1285. {
  1286.   return compare(x, t) > 0; 
  1287. }
  1288.  
  1289. inline int operator>=(const SubString& x, const char* t) 
  1290. {
  1291.   return compare(x, t) >= 0; 
  1292. }
  1293.  
  1294. inline int operator<(const SubString& x, const char* t)  
  1295. {
  1296.   return compare(x, t) < 0; 
  1297. }
  1298.  
  1299. inline int operator<=(const SubString& x, const char* t) 
  1300. {
  1301.   return compare(x, t) <= 0; 
  1302. }
  1303.  
  1304.  
  1305. // a helper needed by at, before, etc.
  1306.  
  1307. inline SubString String::_substr(int first, int l)
  1308. {
  1309.   if (first < 0 || (unsigned)(first + l) > length() )
  1310.     return SubString(_nilString, 0, 0) ;
  1311.   else 
  1312.     return SubString(*this, first, l);
  1313. }
  1314.  
  1315. #endif
  1316.